package com.school.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.school.config.JwtUtils;
import com.school.domain.dto.PhonePwdLoginDTO;
import com.school.domain.dto.UserNamePwdLoginDTO;
import com.school.domain.dto.UserRegisterDTO;
import com.school.domain.po.User;
import com.school.domain.vo.user.LoginVO;
import com.school.domain.vo.user.UserInfoVO;
import com.school.domain.vo.user.UserLoginVO;
import com.school.mapper.UserDao;
import com.school.service.UserService;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author Forever
 * @since 2025-07-05
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {
    @Resource
    private BCryptPasswordEncoder passwordEncoder;

    @Resource
    private JwtUtils jwtUtils;

    @NotNull
    private UserLoginVO getUserLoginVO(User user) {
        LoginVO loginVO = BeanUtil.toBean(user, LoginVO.class);
        // 获取用户信息
        UserInfoVO userInfoVO = BeanUtil
                .copyProperties(user, UserInfoVO.class, "userId");
        // 获取Token
        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setToken(jwtUtils.TWTToken(loginVO));
        userLoginVO.setUserInfo(userInfoVO);
        return userLoginVO;
    }

    @Override
    public UserLoginVO loginByPhone(PhonePwdLoginDTO login) {
        User user = lambdaQuery()
                .eq(User::getPhone, login.getPhone())
                .select(User::getUserId, User::getUsername,
                        User::getEmail, User::getRealName,
                        User::getPhone, User::getPasswordHash,
                        User::getCreateTime)
                .one();
        if (ObjUtil.isNull(user) || !passwordEncoder.matches(login.getPwd(), user.getPasswordHash())) {
            throw new RuntimeException("登录的手机号或者密码错误");
        }
        // 修改最后登录时间
        lambdaUpdate()
                .eq(User::getUserId, user.getUserId())
                .set(User::getLastLogin, LocalDateTime.now())
                .update();
        return getUserLoginVO(user);
    }

    @Override
    public UserLoginVO loginByUserName(UserNamePwdLoginDTO login) {
        User user = lambdaQuery()
                .eq(User::getUsername, login.getUserName())
                .select(User::getUserId, User::getUsername,
                        User::getEmail, User::getRealName,
                        User::getPhone, User::getPasswordHash,
                        User::getCreateTime)
                .one();
        if (ObjUtil.isNull(user) || !passwordEncoder.matches(login.getPwd(), user.getPasswordHash())) {
            throw new RuntimeException("用户名或密码错误");
        }
        // 修改最后登录时间
        lambdaUpdate()
                .eq(User::getUserId, user.getUserId())
                .set(User::getLastLogin, LocalDateTime.now())
                .update();
        return getUserLoginVO(user);
    }

    @Override
    public String userRegister(UserRegisterDTO register) {
        // 检查手机号和邮箱是否已存在
        if (register.getPhone() == null
                || register.getEmail() == null
                || register.getPassword() == null)
            throw new RuntimeException("未填写手机号或者邮箱或者密码");
        //转换对象
        User user = BeanUtil.toBean(register, User.class);
        //设置默认头像
        String encryptedPassword = passwordEncoder.encode(register.getPassword());
        user.setPasswordHash(encryptedPassword);
        //保存用户
        boolean save = save(user);
        if (!save) throw new RuntimeException("注册失败");
        return "注册成功";
    }

}
